//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2006
//
// Object filter by type.
//

# include "StdAfx.h"
# include "Resource.h"
# include "TypeFilter.h"
# include "Types.h"
# include "Map.h"
# include "Settings.h"
# include "ParseHelpers.h"
# include "Globals.h"

CTypeFilter::CTypeFilter () {
	const size_t cStreamLen = GetSettingLen ("FilterTypes") + 1;
	char * const strStream = (char *) alloca (sizeof (char)*cStreamLen);
	GetSetting ("FilterTypes", strStream, cStreamLen, NULL);

	const char * p = strStream;
	const char * const pEnd = strStream + cStreamLen;
	unsigned long ul = 0;
	if (! ParseDecU (p, pEnd, & p, ul))
		return;

	const size_t cTypes = ul;
	m_SelectedTypes.reserve (cTypes);

	for (size_t c = 0; c < cTypes; ++ c) {
		OmitSpaces (& p, pEnd);
		if (! ParseDecU (p, pEnd, & p, ul))
			return;
		const RGN_KIND Kind = ul < rkMax ? static_cast<RGN_KIND> (ul) : rkPoint;

		OmitSpaces (& p, pEnd);
		if (! ParseHex (p, pEnd, & p, ul))
			return;
		const USHORT ushType = ul;

		m_SelectedTypes.push_back (selected_type_t ());
		selected_type_t & st = m_SelectedTypes.back ();
		st.Kind    = Kind;
		st.ushType = ushType;
	}
}

bool CTypeFilter::ShowSettings (HWND _hWnd) {
	const CTypeSet * pTypeSet = NULL;
	{
		CCritSec::CLock lock (g_cs);
		pTypeSet = g_map.pTypeSet;
	}

	if (! SelectMultipleTypes (_hWnd, pTypeSet, m_SelectedTypes))
		return false;

	// Save selected types to registry.
	const size_t cTypes = m_SelectedTypes.size ();
	const size_t cStreamLen = cTypes*8 + 10;
	char * const strStream = (char *) alloca (sizeof (char)*(cStreamLen + 1));
	size_t cOffset = 0;

	cOffset += ::sprintf (strStream + cOffset, "%d ", cTypes);

	for (size_t c = 0; c < cTypes; ++ c) {
		assert (cOffset < cStreamLen);
		if (cOffset + 8 >= cStreamLen)
			break;
		const selected_type_t & st = m_SelectedTypes [c];
		cOffset += ::sprintf (strStream + cOffset, "%d %04x ", st.Kind, st.ushType);
	}
	if (cOffset >= cStreamLen)
		cOffset = cStreamLen;
	strStream [cOffset] = '\0';

	SaveSetting ("FilterTypes", strStream);

	return true;
}

void CTypeFilter::GetName (string_t & _strName) const {
	_strName.append ("type");
}

bool CTypeFilter::DoesFit (const rgn_t & _rgn) const {
	if (_rgn.IsWTR ())
		return false;
	return IsTypeSelected (m_SelectedTypes, static_cast<RGN_KIND> (_rgn.Kind), _rgn.ushType);
}
